#include "PointItem.h"

#include <QtQuick/qsgnode.h>
#include <QtQuick/qsgflatcolormaterial.h>

PointItem::PointItem(QQuickItem *parent)
  : ShapeItem(parent)
  , m_pos(0, 0)
  , m_pointType(Regular)
{
    setFlag(ItemHasContents, true);
}

void PointItem::setPos(const QPointF &p)
{
    if (p == m_pos)
        return;

    m_pos = p;
    emit posChanged(p);
    update();
}

void PointItem::setPointType(PointType pointType)
{
    if (pointType == m_pointType)
        return;

    m_pointType = pointType;
    emit pointTypeChanged(pointType);
    update();
}

QSGNode *PointItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
{
    QSGGeometryNode *node = 0;
    QSGGeometry *geometry = 0;
    GLenum drawingMode = GL_LINES;
    QSGNode::Flag flag = QSGNode::OwnsGeometry;
    if(m_pointType == Regular || m_pointType == Control || m_pointType == Center)
    {
        if(m_selected){
            flag = QSGNode::OwnsOpaqueMaterial;
            drawingMode = GL_QUADS;
        }
        else
            drawingMode = GL_LINE_LOOP;
    }
    else if(m_pointType == Mark)
    {
        drawingMode = GL_LINES;
    }

    if (!oldNode) {
        node = new QSGGeometryNode;
        geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 4);
        geometry->setLineWidth(1);
        node->setGeometry(geometry);

        QSGFlatColorMaterial *material = new QSGFlatColorMaterial;
        material->setColor(QColor(255, 255, 0));
        node->setMaterial(material);
        node->setFlag(QSGNode::OwnsMaterial);
    } else {
        node = static_cast<QSGGeometryNode *>(oldNode);
        geometry = node->geometry();
        geometry->allocate(4);
    }

    geometry->setDrawingMode(drawingMode);
    node->setFlag(flag);

    QSGGeometry::Point2D *vertices = geometry->vertexDataAsPoint2D();
    if(m_pointType == Regular || m_pointType == Center)
    {
        vertices[0].set(m_pos.x() - 5, m_pos.y() - 5);
        vertices[1].set(m_pos.x() - 5, m_pos.y() + 5);
        vertices[2].set(m_pos.x() + 5, m_pos.y() + 5);
        vertices[3].set(m_pos.x() + 5, m_pos.y() - 5);
    }
    else if(m_pointType == Control)
    {
        vertices[0].set(m_pos.x() - 5, m_pos.y());
        vertices[1].set(m_pos.x() , m_pos.y() + 5);
        vertices[2].set(m_pos.x() + 5, m_pos.y());
        vertices[3].set(m_pos.x(), m_pos.y() - 5);
    }
    else if(m_pointType == Mark)
    {
        vertices[0].set(m_pos.x() - 5, m_pos.y() - 5);
        vertices[1].set(m_pos.x() + 5, m_pos.y() + 5);
        vertices[2].set(m_pos.x() - 5, m_pos.y() + 5);
        vertices[3].set(m_pos.x() + 5, m_pos.y() - 5);
    }
    node->markDirty(QSGNode::DirtyGeometry);

    return node;
}
